import { defineStore } from 'pinia'
import { find, groupBy, map, omit } from 'lodash-es'
import {
	createWallet,
	getAllCards,
	getBankList,
	getCryptoAddresses,
	getCryptoChannel,
	getDepositChannel,
	getFiatDepositChannel,
	getFiatWithdrawChannel,
	getFiatWithdrawFee,
	getUserBalance,
	getUserWalletAddress,
	getUserWalletConfig,
	getWalletConfigList,
	getWithdrawChannel,
	updateUserWalletConfig
} from '@/api/wallet.ts'
import { UsdtNetwork } from '@/enums'
import { useAccountStore, useCurrencyStore, useProfileStore } from '@/store'
import {
	AccountShowType,
	BalanceItem,
	BalanceList,
	CardsListType,
	ChannelInfoType,
	CreateWallet,
	FaitWithdrawFeeList,
	FiatPayChannelList,
	NetworkAddressItem,
	PatchWallet,
	PatchWalletEnum,
	UpdateWalletConfig,
	WalletConfig,
	WalletConfigEnum
} from '@/types'
import { calcExchangeRate, Decimals, showError } from '@/utils'
import router from '@/router'
import { getDepositBonus } from '@/api/activity.ts'

let timer: any = null
export const useWalletStore = defineStore('wallet', {
	state: () => ({
		balance: 0,
		// balanceCur: null as BalanceItem | null, // 已改为getters
		balanceList: [] as BalanceList,
		walletConfig: {
			displayCryptoInFiat: false,
			hideZeroBalance: false,
			selectedCryptoCurrency: 'USDT',
			selectedFiatCurrency: 'USD',
			sortedCurrency: [],
			expandFiat: false,
			expandCrypto: true
		} as WalletConfig,
		// wallet 是用户钱包相关,退出登录时会被重置
		// 货币相关的 exchangeRate, fiatList, cryptoList 迁移到了 currencyStore
		walletDepositShow: false,
		walletWithdrawShow: false,
		walletSettingShow: false,
		walletUnlockShow: false,
		show: {
			submitFiatDepositResult: false
		},
		loading: {
			balanceList: false,
			createWallet: false,
			depositBonus: false,
			cryptoDepositChannel: false,
			cryptoWithdrawChannel: false,
			fiatDepositChannel: false,
			fiatWithdrawChannel: false,
			fiatWithdrawFee: false
		},
		depositBonus: null as Record<string, any> | null,
		cryptoDepositChannel: null as any[] | null,
		cryptoWithdrawChannel: null as any[] | null,
		fiatDepositChannel: null as FiatPayChannelList | null,
		submitFiatDepositParams: null as any | null,
		submitFiatDepositResult: null as any | null,
		fiatWithdrawChannel: null as any | null,
		fiatWithdrawFee: null as FaitWithdrawFeeList[] | null,
		// freezeAmount: 0,
		// frozenBalance: 0,
		cards: [] as CardsListType,
		addresses: [
			{
				id: '',
				text: '',
				textT: '',
				icon: ''
			}
		] as any,
		channelInfo: {
			channelList: [] as any
		} as ChannelInfoType,
		bankList: [],
		withdrawChannel: {
			flat: false,
			crypto: false,
			withdrawAble: false,
			unCompleteTaskAmount: '',
			allTaskNum: 0
		},
		showValidate: false,
		showWithdrawValidate: false,
		showCompleteDialog: false,
		isShowWalletPopup: false,
		showWalletDepositNextPopup: false,
		showWalletUsdtAddressSelectPopup: false,
		showWalletBankCardSelectPopup: false,
		showWithdrawPopup: false,
		showWithdrawResultPopup: false,
		showPaymentHistory: false,
		depositBankPaymentList: [],
		depositData: {
			currentType: '',
			cryptoCode: '',
			selectedBank: {}
		} as any,
		withdrawData: { type: '', id: '', resultId: '', success: null } as any,
		dw: true // 数字货币充提系统开关状态
	}),
	actions: {
		setValidateShow(value: boolean) {
			this.showValidate = value
		},
		setWalletDepositShow(value: boolean) {
			const profileStore = useProfileStore()
			if (value && profileStore.lockWallet) {
				this.walletUnlockShow = true
				return
			}
			value
				? router.replace({ query: { tab: 'crypto', modal: 'wallet-deposit' } })
				: router.replace({ query: {} })
			this.walletDepositShow = value
		},
		setWalletWithdrawShow(value: boolean) {
			const profileStore = useProfileStore()
			if (value && profileStore.lockWallet) {
				this.walletUnlockShow = true
				return
			}
			value
				? router.replace({ query: { tab: 'withdraw-crypto', modal: 'wallet-withdraw' } })
				: router.replace({ query: {} })
			this.walletWithdrawShow = value
		},
		showWalletDeposit() {
			this.walletDepositShow = true
		},
		showWalletWithdraw() {
			this.walletWithdrawShow = true
		},
		setWalletSettingShow(value: boolean) {
			value ? router.replace({ query: { modal: 'wallet-setting' } }) : router.replace({ query: {} })
			this.walletSettingShow = value
		},
		showWalletSetting() {
			this.walletSettingShow = true
		},
		setWithdrawValidateShow(value: boolean) {
			this.showWithdrawValidate = value
		},
		setWalletPopupShow(value: boolean) {
			this.isShowWalletPopup = value
		},
		setWalletDepositNextPopupShow(value: boolean) {
			this.showWalletDepositNextPopup = value
		},
		setWalletUsdtAddressSelectPopupShow(value: boolean) {
			this.showWalletUsdtAddressSelectPopup = value
		},
		setWalletBankCardSelectPopupShow(value: boolean) {
			this.showWalletBankCardSelectPopup = value
		},
		setWithdrawPopupShow(value: boolean) {
			this.showWithdrawPopup = value
		},
		setWithdrawResultPopupShow(value: boolean) {
			this.showWithdrawResultPopup = value
		},
		setPaymentHistoryShow(value: boolean) {
			this.showPaymentHistory = value
		},
		setDepositData(data: any) {
			this.depositData = { ...this.depositData, ...data }
		},
		setWithdrawData(data: any) {
			this.withdrawData = { ...this.withdrawData, ...data }
		},
		setDepositBankPaymentList(data: any) {
			this.depositBankPaymentList = data
		},
		setBalance(data: BalanceList) {
			this.balanceList = data?.map((item) => Object.assign({ freeAmount: '0' }, item))
			if (import.meta.env.DEV) {
				// this.balanceList.forEach((item) => {
				// 	if (item.currency === 'CNY') item.freeAmount = '50000'
				// })
			}
		},
		patchWallet<T extends PatchWalletEnum>(type: T, data: PatchWallet[T]) {
			switch (type) {
				case PatchWalletEnum.balanceItem: {
					const { currency, freeAmount } = <PatchWallet[PatchWalletEnum.balanceItem]>data
					const balance = find(this.balanceList, { currency })
					balance && Object.assign(balance, { freeAmount })
					if (import.meta.env.DEV) {
						// if (balance && currency === 'CNY') balance.freeAmount = '50000'
					}
					break
				}
				case PatchWalletEnum.balanceList: {
					const _data = <PatchWallet[PatchWalletEnum.balanceList]>data
					_data.forEach((item) => this.patchWallet(PatchWalletEnum.balanceItem, item))
					break
				}
				case PatchWalletEnum.addressItem: {
					const { currency, thirdAssetId } = <PatchWallet[PatchWalletEnum.addressItem]>data
					const balance = find(this.balanceList, { currency }) as BalanceItem | null
					const network = find(balance?.userAssets, { thirdAssetId })
					network && Object.assign(network, omit(data, ['currency']))
					break
				}
				case PatchWalletEnum.addressList: {
					const _data = <PatchWallet[PatchWalletEnum.addressList]>data
					_data.forEach((item) => this.patchWallet(PatchWalletEnum.addressItem, item))
					break
				}
			}
		},
		// 获取钱包基础数据结构
		async getWalletConfigList() {
			try {
				this.loading.balanceList = true
				const { data } = await getWalletConfigList()
				this.setBalance(data)
				await Promise.all([this.getBalance(), this.getUserWalletAddress()])
			} catch (err) {
				showError(err as string)
			} finally {
				this.loading.balanceList = false
			}
		},
		// 获取钱包余额->合并到基础结构
		async getBalance(time?: number) {
			const accountStore = useAccountStore()
			if (!accountStore.isLogin) return
			try {
				if (timer) clearTimeout(timer)
				const { data } = await getUserBalance()
				this.patchWallet(PatchWalletEnum.balanceList, data)
			} catch {
			} finally {
				timer = setTimeout(() => this.getBalance(time), time ? time : 60000)
			}
		},
		// 获取钱包地址->合并到基础结构
		async getUserWalletAddress() {
			try {
				const { data } = await getUserWalletAddress()
				this.patchWallet(PatchWalletEnum.addressList, data)
			} catch (err) {
				showError(err as string)
			}
		},
		// 获取用户钱包配置
		async getUserWalletConfig() {
			try {
				const { data } = await getUserWalletConfig()
				this.walletConfig = {
					...this.walletConfig,
					...data,
					[WalletConfigEnum.displayCryptoInFiat]: JSON.parse(String(data.displayCryptoInFiat)),
					[WalletConfigEnum.hideZeroBalance]: JSON.parse(String(data.hideZeroBalance))
				}
			} catch {}
		},
		async setBalanceCur(data: BalanceItem) {
			if (data.currency !== this.walletConfig.selectedCryptoCurrency) {
				await this.updateUserWalletConfig({
					confCode: WalletConfigEnum.selectedCryptoCurrency,
					confValue: data.currency
				})
			}
		},
		// 修改用户钱包配置
		async updateUserWalletConfig<T extends keyof WalletConfig>(data: UpdateWalletConfig<T>) {
			await updateUserWalletConfig(data)
			this.walletConfig[data.confCode] = data.confValue
		},
		// 创建钱包存款地址,存款时如果地址不存在则创建
		async createWallet(params: CreateWallet['params']) {
			try {
				this.loading.createWallet = true
				const { data } = <{ data: CreateWallet['result'] }>await createWallet(params)
				if (data) {
					const balance = find(this.balanceList, { currency: params.currency })
					const network = find(balance?.userAssets, { thirdAssetId: params.thirdAssetId })
					network && Object.assign(network, omit(data, ['cpn']))
				}
				return data
			} catch (err) {
				showError(err as string)
			} finally {
				this.loading.createWallet = false
			}
		},
		// 存款奖金
		async getDepositBonus() {
			try {
				this.loading.depositBonus = true
				const { data } = await getDepositBonus()
				// this.depositBonus = {
				// 	minDepositAmount: 300.0,
				// 	bonusPercentage: 200.0,
				// 	maxBonusAmount: 400.0
				// }
				this.depositBonus = data
			} catch (error) {
				showError(error)
			} finally {
				this.loading.depositBonus = false
			}
		},
		// 虚拟币存款渠道
		async getCryptoDepositChannel() {
			try {
				this.loading.cryptoDepositChannel = true
				const { data } = await getCryptoChannel({ type: 1 })
				this.cryptoDepositChannel = data
			} catch (error) {
				showError(error)
			} finally {
				this.loading.cryptoDepositChannel = false
			}
		},
		// 虚拟币提款渠道
		async getCryptoWithdrawChannel() {
			try {
				this.loading.cryptoWithdrawChannel = true
				const { data } = await getCryptoChannel({ type: 2 })
				this.cryptoWithdrawChannel = data
			} catch (error) {
				showError(error)
			} finally {
				this.loading.cryptoWithdrawChannel = false
			}
		},
		// 法币存款渠道
		async getFiatDepositChannel() {
			try {
				this.loading.fiatDepositChannel = true
				const { data } = await getFiatDepositChannel()
				this.fiatDepositChannel = map(groupBy(data, 'assetId'), (payTypeList, currency) => ({
					currency,
					payTypeList: map(groupBy(payTypeList, 'payTypeId'), (payMethodList, payTypeId) => ({
						payTypeId: Number(payTypeId),
						payTypeName: payMethodList[0].payTypeName,
						payMethodList
					}))
				})) as FiatPayChannelList
			} catch (error) {
				console.error(error)
				showError(error)
				this.fiatDepositChannel = null
			} finally {
				this.loading.fiatDepositChannel = false
			}
		},
		// 法币提款渠道
		async getFiatWithdrawChannel() {
			try {
				this.loading.fiatWithdrawChannel = true
				const { data } = await getFiatWithdrawChannel()
				this.fiatWithdrawChannel = map(groupBy(data, 'assetId'), (bankList, currency) => ({
					currency: currency,
					bankFlag: bankList[0]?.bankFlag,
					bankList
				}))
			} catch (error) {
				console.error(error)
				showError(error)
				this.fiatWithdrawChannel = null
			} finally {
				this.loading.fiatWithdrawChannel = false
			}
		},
		// 法币提款费率
		async getFiatWithdrawFee() {
			try {
				this.loading.fiatWithdrawFee = true
				const { data } = await getFiatWithdrawFee()
				// {
				// 	"maxAmount": "50000",
				// 	"minAmount": "200",
				// 	"fixed": "1",
				// 	"percent": "2.5",
				// 	"assetId": "CNY_GB"
				// }
				if (import.meta.env.DEV) {
					// data?.forEach((i: any) => {
					// 	i.fixed = '1'
					// 	i.percent = '2.5'
					// })
				}
				this.fiatWithdrawFee = data
			} catch (error) {
				console.error(error)
				showError(error)
				this.fiatWithdrawFee = null
			} finally {
				this.loading.fiatWithdrawFee = false
			}
		},
		async getAllCards() {
			try {
				const { data } = await getAllCards()
				this.cards = data
			} catch {}
		},
		async getBanks() {
			try {
				const { data } = await getBankList()
				this.bankList = data
			} catch {}
		},
		async getCryptoAddresses() {
			try {
				const { data } = await getCryptoAddresses()
				this.addresses = data.filter((item: any) => item.network === UsdtNetwork.trx.id)
			} catch {}
		},
		async getChannelInfo() {
			try {
				const { data } = await getDepositChannel()
				this.channelInfo = data
				if (this.channelInfo.channelList?.length) {
					this.channelInfo.channelList = this.channelInfo?.channelList.filter(
						(item: any) => this.dw || item.paymentMethod !== 'USDT'
					)
				}
			} catch {}
		},
		async getWithdrawChannel() {
			try {
				const { data } = await getWithdrawChannel()
				this.withdrawChannel = data
			} catch {}
		},
		validateNavigation() {
			const profileStore = useProfileStore()
			const accountStore = useAccountStore()
			const email = profileStore.userInfo?.email
			const mobile = profileStore.userInfo?.mobile
			const bankCards = profileStore.userInfo?.bankCards
			if (!accountStore.isLogin) {
				return accountStore.showAccount(AccountShowType.login)
			} else if (!email && !mobile && !bankCards?.length) {
				this.setValidateShow(true)
			} else {
				this.setWalletPopupShow(true)
			}
		}
	},
	getters: {
		balanceCur: (state) => {
			const { displayCryptoInFiat, selectedCryptoCurrency, selectedFiatCurrency } =
				state.walletConfig
			const balance = find(state.balanceList, {
				currency: selectedCryptoCurrency
			}) as BalanceItem | null
			if (balance) {
				state.balance = Number(balance?.freeAmount)
				balance.currentAmount = calcExchangeRate(
					balance.currency,
					displayCryptoInFiat ? selectedFiatCurrency : selectedCryptoCurrency,
					balance.freeAmount
				)
			}
			return balance
		},
		// 当前是否开启了法币显示 ? 选择的法币 : false;
		fiatOrFalse: (state) => {
			return state.walletConfig.displayCryptoInFiat
				? state.walletConfig.selectedFiatCurrency
				: false
		},
		// 所有钱包货币转换为选定法币的总金额
		totalBalance: (state) => {
			const currencyStore = useCurrencyStore()
			return state.balanceList.reduce((pre, item) => {
				const currencyFrom = item.currency
				const currencyTo = state.walletConfig.selectedFiatCurrency
				const amountFrom = item?.freeAmount || 0
				let usd: number | string = 0
				if (currencyFrom === currencyTo) usd = amountFrom
				const mul = currencyStore.exchangeRate[currencyFrom]?.[currencyTo]
				const div = currencyStore.exchangeRate[currencyTo]?.[currencyFrom]
				if (mul) usd = Decimals.mul(amountFrom, mul)
				if (div) usd = Decimals.div(amountFrom, div)
				return Decimals.add(pre, usd)
			}, 0)
		},
		// 所有加密货币钱包的存款地址
		allDepositWalletAddress: (state) => {
			const list = <NetworkAddressItem['walletAddress'][]>[]
			state.balanceList?.forEach((item) => {
				item.userAssets?.forEach((item2) => {
					!!item2.walletAddress && list.push(item2.walletAddress)
				})
			})
			return list
		}
	},
	persist: true
})
